package net.sourceforge.peers;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import net.sourceforge.peers.sip.Utils;

/**
 * 日志类
 * @author Mr.Yan
 */
public class FileLogger implements Logger {

    public final static String LOG_FILE = File.separator + "logs"
        + File.separator + "peers.log";
    public final static String NETWORK_FILE = File.separator + "logs"
        + File.separator + "transport.log";

    private PrintWriter logWriter;
    private PrintWriter networkWriter;
    private final Object logMutex;
    private final Object networkMutex;
    private final SimpleDateFormat logFormatter;
    private final SimpleDateFormat networkFormatter;

    public FileLogger(String peersHome) {
        if (peersHome == null) {
            peersHome = Utils.DEFAULT_PEERS_HOME;
        }
        try {
            logWriter = new PrintWriter(new BufferedWriter(
                    new FileWriter(peersHome + LOG_FILE)));
            networkWriter = new PrintWriter(new BufferedWriter(
                    new FileWriter(peersHome + NETWORK_FILE)));
        } catch (IOException e) {
            System.out.println("logging to stdout");
            logWriter = new PrintWriter(System.out);
            networkWriter = new PrintWriter(System.out);
        }
        logMutex = new Object();
        networkMutex = new Object();
        logFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
        networkFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
    }

    @Override
    public final void debug(String message) {
        synchronized (logMutex) {
            logWriter.write(genericLog(message, "DEBUG"));
            logWriter.flush();
        }
    }

    @Override
    public final void info(String message) {
        synchronized (logMutex) {
            logWriter.write(genericLog(message, "INFO "));
            logWriter.flush();
        }
    }

    @Override
    public final void error(String message) {
        synchronized (logMutex) {
            logWriter.write(genericLog(message, "ERROR"));
            logWriter.flush();
        }
    }

    @Override
    public final void error(String message, Exception exception) {
        synchronized (logMutex) {
            logWriter.write(genericLog(message, "ERROR"));
            exception.printStackTrace(logWriter);
            logWriter.flush();
        }
    }
    
    private String genericLog(String message, String level) {

        return logFormatter.format(new Date()) +
                " " +
                level +
                " [" +
                Thread.currentThread().getName() +
                "] " +
                message +
                "\n";
    }

    @Override
    public final void traceNetwork(String message, String direction) {
        synchronized (networkMutex) {
            String buf = networkFormatter.format(new Date()) +
                    " " +
                    direction +
                    " [" +
                    Thread.currentThread().getName() +
                    "]\n\n" +
                    message +
                    "\n";
            networkWriter.write(buf);
            networkWriter.flush();
        }
    }

}
